﻿/*
 * Erstellt mit SharpDevelop.
 * Benutzer: Kai Patrick
 * Datum: 01.04.2008
 * Zeit: 13:39
 * 
 * Sie können diese Vorlage unter Extras > Optionen > Codeerstellung > Standardheader ändern.
 */

using System;
using System.Collections.Generic;
using MSAst = Microsoft.Scripting.Ast;
using Gamadus.Engine;

namespace Gamadus.Engine.Compiler.Ast
{
	/// <summary>
	/// Description of Function.
	/// </summary>
	public class Function : Expression
	{
		readonly string m_name;
		readonly Expression[] m_arguments;
			
		public Function(Irony.Compiler.AstNode node) : base(node)
		{
			m_name = (node.ChildNodes[0] as Irony.Compiler.Token).Text;
			if(node.ChildNodes.Count == 1)
			{
				m_arguments = new Expression[0]; // no arguments
			}
			else if(node.ChildNodes[1].Term.Name == "Expr_list")
			{
				m_arguments = new Expression[node.ChildNodes[1].ChildNodes.Count];
				int i = 0;
				foreach(Irony.Compiler.AstNode child in node.ChildNodes[1].ChildNodes)
				{
					m_arguments[i++] = Expression.MakeExpression(child);
				}
			}
			else
			{
				m_arguments = new Expression[] {Expression.MakeExpression(node.ChildNodes[1])};
			}
		}
		
		protected internal override Microsoft.Scripting.Ast.Expression Generate()
		{
			System.Reflection.MethodInfo method = typeof(GML).GetMethod(m_name);
			if(method == null)
				throw new ApplicationException("Function "+m_name+" does not exist");
			MSAst.Expression[] expressions = new MSAst.Expression[m_arguments.Length];
			int i = 0;
			foreach(Expression expr in m_arguments)
			{
				expressions[i] = MSAst.Ast.ConvertHelper(m_arguments[i].Generate(), typeof(GmlVar));
				i++;
			}
			return MSAst.Ast.Statement(
                Span,
                MSAst.Ast.Call(method, expressions)
            );
		}
		
		public override string ToString()
		{
			string ret = "Function call: "+m_name+"(";
			foreach(Expression expr in m_arguments)
			{
				ret += expr.ToString()+", ";
			}
			ret = (m_arguments.Length > 0 ? ret.Substring(0, ret.Length-2) : ret) +")";
			return ret;
		}
	}
}
